package com.yoda.youdianda.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yoda.youdianda.common.ErrorResult;
import com.yoda.youdianda.common.R;
import com.yoda.youdianda.common.RC;
import com.yoda.youdianda.common.ThreadContext;
import com.yoda.youdianda.domain.*;
import com.yoda.youdianda.dto.*;
import com.yoda.youdianda.exception.BusinessException;
import com.yoda.youdianda.mapper.*;
import com.yoda.youdianda.service.*;
import com.yoda.youdianda.util.Util;
import com.yoda.youdianda.vo.*;
import lombok.AllArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.*;
import java.util.stream.Collectors;

//前台用户相关
@Service
@AllArgsConstructor
public class UserServiceImpl implements UserService {


    @Autowired
    private YddUserDataService yddUserDataService;

    @Autowired
    private YddUserService yddUserService;

    @Autowired
    private YddArticleService yddArticleService;

    @Autowired
    private YddCateService yddCateService;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;


    @Override
    public R<String> save(YddArticleDto yddArticleDto) {
        yddArticleService.insert(yddArticleDto);
        return R.success("保存成功!");
    }

    @Override
    public R<String> del(int id) {
        yddArticleService.deleteById(id);
        return R.success("删除成功");
    }

    @Override
    public UserLoginFrontVo getUserInfo() {
        String userId = ThreadContext.getId(RC.YDD_ID);
        //获取收藏数
        LambdaQueryWrapper<YddUserData> collectLqw = new LambdaQueryWrapper<>();
        collectLqw.eq(StringUtils.isNotEmpty(userId), YddUserData::getUserId, userId);
        collectLqw.eq(YddUserData::getType, 1);
        Integer collectCount = yddUserDataService.selectCount(collectLqw);
        //获取点赞数
        LambdaQueryWrapper<YddUserData> zanLqw = new LambdaQueryWrapper<>();
        zanLqw.eq(StringUtils.isNotEmpty(userId), YddUserData::getUserId, userId);
        zanLqw.eq(YddUserData::getType, 2);
        Integer zanCount = yddUserDataService.selectCount(zanLqw);
        //获取用户信息
        YddUser yddUser = yddUserService.selectById(userId);
        //获取发布文章数
        LambdaQueryWrapper<YddArticle> lqw = new LambdaQueryWrapper<>();
        lqw.eq(StringUtils.isNotEmpty(userId), YddArticle::getUserId, userId);
        Integer count = yddArticleService.selectCount(lqw);
        return new UserLoginFrontVo(count, collectCount, zanCount, yddUser);
    }

    /**
     * 分页查询个人文章
     *
     * @param page     页面
     * @param pageSize 页面大小
     * @return {@link ArticleVo}
     */
    @Override
    public PageResult<ArticleVo> selectByPage(Integer page, Integer pageSize) {
        Integer id = Integer.parseInt(Objects.requireNonNull(ThreadContext.getId(RC.YDD_ID)));
        return yddArticleService.selectByPage(page,pageSize,id);
    }

    @Override
    public void updateUserInfo(YddUser yddUser) {
        yddUserService.updateUserInfo(yddUser);
    }

    /**
     * 用户点赞或者收藏文章
     *
     * @param articleId 文章id
     * @param type      类型
     */
    @Override
    public void addYddUserData(Integer articleId, Integer type) {
        String userId = ThreadContext.getId(RC.YDD_ID);
        //查询redis是否已点赞或者已收藏文章
        String key = RC.ARTICLE_KEY+articleId+RC.USER_ID_VALUE+userId;
        String likeValue =RC.BEHAVIOR_VALUE+RC.LIKE_VALUE ;
        String collectValue =RC.BEHAVIOR_VALUE+RC.COLLECT_VALUE ;
        Boolean isLiked = redisTemplate.opsForHash().hasKey(key, likeValue);
        Boolean isCollect = redisTemplate.opsForHash().hasKey(key, collectValue);
        if (Objects.equals(type, RC.COLLECT_VALUE)&&isCollect){
            //重复收藏
            throw new BusinessException(ErrorResult.builder().errorMessage("重复收藏").errorCode(1).build());

        }else if (Objects.equals(type, RC.LIKE_VALUE)&&isLiked){
            //重复点赞
            throw new BusinessException(ErrorResult.builder().errorMessage("重复点赞").errorCode(1).build());
        }
        //保存数据
        yddUserDataService.addYddUserData(articleId,type);
        if (Objects.equals(type, RC.COLLECT_VALUE)){
            redisTemplate.opsForHash().put(key,collectValue,"1");
        }else if (Objects.equals(type, RC.LIKE_VALUE)){
            redisTemplate.opsForHash().put(key,likeValue,"1");
        }
    }

    @Override
    public void delYddUserData(Integer articleId, Integer type) {
        String userId = ThreadContext.getId(RC.YDD_ID);
        String key = RC.ARTICLE_KEY+articleId+RC.USER_ID_VALUE+userId;
        String likeValue =RC.BEHAVIOR_VALUE+RC.LIKE_VALUE ;
        String collectValue =RC.BEHAVIOR_VALUE+RC.COLLECT_VALUE ;
        Boolean isLiked = redisTemplate.opsForHash().hasKey(key, likeValue);
        Boolean isCollect = redisTemplate.opsForHash().hasKey(key, collectValue);
        if (Objects.equals(type, RC.COLLECT_VALUE)&&!isCollect){
            //重复取消收藏
            throw new BusinessException(ErrorResult.builder().errorMessage("重复取消收藏").errorCode(1).build());

        }else if (Objects.equals(type, RC.LIKE_VALUE)&&!isLiked){
            //重复取消点赞
            throw new BusinessException(ErrorResult.builder().errorMessage("重复取消点赞").errorCode(1).build());
        }
        yddUserDataService.delYddUserData(articleId,type);
        if (Objects.equals(type, RC.COLLECT_VALUE)){
            redisTemplate.opsForHash().delete(key,collectValue);
        }else if (Objects.equals(type, RC.LIKE_VALUE)){
            redisTemplate.opsForHash().delete(key,likeValue);
        }
    }

    @Override
    public R<String> update(YddArticleDto yddArticleDto) {
        return yddArticleService.upd(yddArticleDto);
    }

    @Override
    public PageResult yddUserDataPage(Integer type,Integer page,Integer limit) {
        Page<YddUserData> yddUserDataPage  = yddUserDataService.yddUserDataPage(type,page,limit);
        List<YddUserData> yddUserDataList = yddUserDataService.getYddUserData(type);
        if(yddUserDataList.size() == 0){
            return new PageResult();
        }
        List<Integer> articleIds = yddUserDataList.stream().map(YddUserData::getArticleId).collect(Collectors.toList());

        List<YddArticle> yddArticleList = yddArticleService.getYddArticle(articleIds);
        List<YddArticleVo> yddArticleVos = yddArticleList.stream().map(yddArticle -> {
            YddArticleVo yddArticleVo = new YddArticleVo();
            BeanUtils.copyProperties(yddArticle, yddArticleVo);
            Integer cateid = yddArticle.getCateid();
            YddCate yddCate = yddCateService.getYddCate(cateid);
            yddArticleVo.setCatename(yddCate.getCatename());
            return yddArticleVo;
        }).collect(Collectors.toList());

        return new PageResult((int) yddUserDataPage.getCurrent(), (int) yddUserDataPage.getSize(), (int) yddUserDataPage.getTotal(), yddArticleVos);
    }
}
